home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Apple II Magazines (PO)
/
Nibble Volume 09, No. 08 (1988-08)(MicroSPARC)(Side A).zip
/
Nibble Volume 09, No. 08 (1988-08)(MicroSPARC)(Side A).po
/
NIBBLETERM.S
< prev
next >
Wrap
Text File
|
1996-12-24
|
33KB
|
1,038 lines
*
* NibbleTerm Source Code
* for NT.OBJ1, NT.OBJ2, NT.OBJ3
*
* by Eric C. Mueller
* Copyright(c) 1988
* MicroSPARC, Inc.
* Concord, MA 01742
*
ORGLOC EQU $9100 ;dec. 37120
ORG ORGLOC ;set origin
TR ON ;shorten printing of ASC and DS
* Jump table (offset is label...i.e. CALL BASE+3 to do TERM)
:0 JMP INIT ;initialize modem & firmware
:3 JMP TERM ;go into terminal mode
:6 JMP DOBAUDCH ;do a baud rate change
:9 JMP DOSHOWT ;toggle show on bottom
:12 HEX EA,EA,EA ;[available hook]
:15 JMP DOASAVE ;toggle autosave on/off
:18 JMP DOBREAK ;do a break send
:21 JMP DODIAL ;dial number in input buffer
:24 JMP WTCNCT ;wait for conn. after dialing
:27 JMP DOBUFF ;do a buffer call (on/off, clr)
:30 JMP PRSTATUS ;print status line
:33 JMP DOHU ;hang up phone
:36 HEX EA,EA,EA ;[available hook]
:39 JMP HOLDMEM ;mark driver memory as used
:42 JMP SNDRTN ;send out a RETURN (to abort dialing)
:45 JMP DOVIEW ;view buffer
:48 JMP DORESTBM ;restore old bitmap
:51 JMP DOFLUSH ;flush input buffer (if one exists)
* Page 3 global equates
AUTOSAVE EQU $300 ;autosave on (128) or off (0)
TEMPRY EQU $301 ;temporary character hold
BUFONOFF EQU $302 ;buffer on (128) or off (0)
BAUDRT EQU $304 ;baud rate: 0=300, 1=1200, 2=2400
IDBYTE EQU $305 ;modem driver ID: 1=IIGS, 2=SSC, 3=?
SHOWFLG EQU $306 ;show info scrollin in (0/128)
* Zero page global equates
EXTPTR EQU $06 ;(and $07) pointer to ext. interface
BUFPTR EQU $E0 ;(and $E1) pointer into buffer
ZPBYTE EQU $08 ;numbers are passed through here
* Other equates
CRSR EQU "_" ;cursor
CH EQU $57B ;cursor horizontal (current HT val)
CV EQU $25 ;as above but for vertical
BUFST EQU $6800 ;buffer start
BUFEND EQU ORGLOC-1 ;buffer end (driver start, too)
SPKR EQU $C030 ;make a click f/the speaker
KEYBRD EQU $C000 ;keyboard (hardware) address
STROBE EQU $C010 ;clear keyboard strobe
OPNAPL EQU $C061 ;open-apple location (>128 = pressed)
WAIT EQU $FCA8 ;wait for time in accum
COUT EQU $FDED ;character out
TABV EQU $FB5B ;do a VTAB
BITMAP EQU $BF58 ;ProDOS memory bitmap
PBFR EQU $0200 ;buffer for string passing
MLI EQU $BF00 ;ProDOS machine lang. interface
********************************
DORESTBM LDA BMS ;has the bit map been saved
BEQ NOTSVD ;no, don't restore it
LDY #23
RESTBM1 LDA ORGBM,Y ;restore original bit map
STA BITMAP,Y
DEY
BPL RESTBM1 ;keep going until done
NOTSVD LDA ZPBYTE ;check zero page loc
CMP #123 ;skip modem end init?
BEQ SKIPMI ;yes
JSR MDMEINIT ;do closing stuff with modem
SKIPMI RTS
********************************
DOSHOWT LDA SHOWFLG ;toggle show line
EOR #%10000000
STA SHOWFLG
BNE SHOWON
LDA #"-"
BNE SHOWCLR
SHOWON LDA #$A0 ;space0
SHOWCLR LDY #1 ;set show line to all spcs or dashes
SHOWOFF STA $7D0,Y
INY
CPY #38
BNE SHOWOFF ;turn show line off
RTS
********************************
HOLDMEM LDY #23 ;save original bit map
HOLDMEM1 LDA BITMAP,Y
STA ORGBM,Y
DEY
BPL HOLDMEM1
LDA #$01 ;yes, the bitmap has been saved
STA BMS
LDA #>BUFST ;get high byte of address
MARK PHA
JSR DOMARK ;mark that page as used
PLA
CMP #$9A ;all the way out?
BEQ DONEMARK
CLC
ADC #$01
BNE MARK ;always
DONEMARK RTS ;return
DOMARK TAX ;mark page in accum. as used
LSR
LSR
LSR
TAY
TXA
AND #$07
TAX
LDA #$80
DOMARK0 DEX
BMI SETBIT
LSR
JMP DOMARK0
SETBIT ORA BITMAP,Y ;turn that bit on (mark it)
STA BITMAP,Y ;save it
RTS
ORGBM DS 24 ;room for original bit map
BMS DFB $00 ;bit map saved flag (t/f; 1/0)
********************************
INIT LDA ZPBYTE ;prepare modem addresses
ORA #$C0
STA EXTPTR+1 ;store $Cn
ASL
ASL
ASL
ASL
STA SPEC ;store $n0
LDA #$00
STA NOCAROFF
STA BUFONOFF ;buffer default = off
STA AUTOSAVE ;autosave default = off
STA EXTPTR
LDA #$80
STA SHOWFLG ;show default = on
LDA #$01 ;default baud = 1200
STA BAUDRT
JSR RESETBUF ;reset buffer
JSR MDMINIT ;do modem-specific init
LDA #$00
BCC OKRTN ;it's okay, return with no errs
LDA #$01
OKRTN STA ZPBYTE ;indicate no error/error cond.
JSR PRSTATUS
RTS ;done with init
SPEC DS 1 ;equal to $n0
********************************
DOBUFF LDA ZPBYTE ;get command...
BPL NORST ;hi bit clr = don't reset it
JSR RESETBUF ;empty buffer out
NORST LDA ZPBYTE
AND #%01111111 ;chop off high bit
BEQ RTN ;not a buffer on/off command
JSR DOCHECK ;check if buffer is full
BNE BUFNOTF ;buffer not full; turn it on
JSR BUZZ0 ;buzz at 'em
RTN RTS ;and exit
BUFNOTF LDA BUFONOFF
EOR #%10000000 ;toggle buffer on/off
STA BUFONOFF ;and that's that!
JSR PRSTATUS ;update status line
JMP RTN
CHKBUFST JSR DOCHECK
BNE NOTFULL
LDA BUFONOFF ;is buffer turned on?
BEQ NOTFULL ;no, don't buzz
LDA #$00
STA BUFONOFF ;turn buffer off (unconditionally)
JSR PRSTATUS ;update status line
LDA AUTOSAVE ;is autosave enabled?
BEQ BUZZ0 ;no, just buzz and return
SEC ;carry set = return to basic for autosave
RTS
NOTFULL CLC
RTS
BUZZ0 LDA #$20 ;buffer is full, make annoying buzz
STA REGX ;hold length of tone
BUZZ1 LDA #$02
JSR WAIT ;wait for a short moment
STA SPKR ;click!
LDA #$24
JSR WAIT ;another tiny wait
STA SPKR ;click!
DEC REGX
BNE BUZZ1
CLC ;even though buffer is full, c=0
RTS
DOCHECK LDA #<BUFEND
SEC
SBC BUFPTR
BNE NOTFULL0
LDA #>BUFEND
SEC
SBC BUFPTR+1
NOTFULL0 RTS
RESETBUF LDA #<BUFST ;reset buffer to empty
STA BUFPTR
LDA #>BUFST ;start of buffer
STA BUFPTR+1
JSR PRSTATUS
RTS
********************************
DOASAVE LDA AUTOSAVE
EOR #%10000000 ;toggle autosave on/off
STA AUTOSAVE
LDA ZPBYTE
AND #%01111111 ;is the high bit set (to clear, too?)
BEQ EXITAS ;no
JSR RESETBUF ;yes, clear buffer out
EXITAS JSR PRSTATUS
RTS
********************************
TERM JSR STRTFLOW ;start input flow (ctrl-Q)
JSR CRSRON ;print initial cursor
LOOP LDA LASTCHAR ;get last character received
JSR CHKCARR ;@@ EXTERNAL HOOK
BCS NOPE ;carry set= no carrier
LDA KEYBRD ;check for local keypress
BMI KEYHIT ;yes, a key has been hit...
LDA OPNAPL ;check for open-apple
BPL INPUT? ;no, open-apple not pressed
LDA #$00 ;open apple pressed---back to basic
TOBASIC STA ZPBYTE
JSR STOPFLOW ;stop input flow (send CTRL-S)
RTS ;return to caller
NOPE LDA #$01 ;problem: no carrier!
BNE TOBASIC ;return to basic
KEYHIT BMI KEYHIT0 ;just a continuation of another branch
INPUT? JSR CHARIN ;@@ EXTERNAL HOOK
BCC NOKEYIN ;no key in...
STA TEMPRY ;hold it here for comparison
CMP #$FF ;is it DELETE?
BEQ NOKEYIN ;yes, ignore it
CMP #$A0
BGE OKPRT ;if it's not a ctrl char, don't check
LDX #$00 ;start at beginning of table
CHKITOUT LDA OKAYCTRL,X ;end of table?
BEQ NOKEYIN ;if at the end of the table, it's not okay
LDA TEMPRY ;get comp. info
CMP OKAYCTRL,X ;is the character okay?
BEQ OKPRT ;yes, it's okay to print
INX
BNE CHKITOUT ;no, keep checking it
OKPRT JSR CRSROFF
JSR COUT
STA LASTCHAR ;last character received
JSR HNDLBFR ;handle buffer
BCC TURNCON ;if autosave not needed, jump over
LDA #$02 ;code 2 = dump buffer (for autosave)
BNE TOBASIC ;(always)
TURNCON JSR CRSRON
GOLOOP JMP LOOP ;back through main term loop
NOKEYIN LDA #$00
STA LASTCHAR
BEQ GOLOOP
CRSROFF PHA
LDA #$A0 ;erase old cursor
JSR COUT
LDA #$88
JSR COUT
PLA
RTS
CRSRON PHA
LDA #CRSR ;put down new cursor
JSR COUT
LDA #$88
JSR COUT
PLA
RTS
KEYHIT0 BIT STROBE ;key accepted; clear keyboard
CMP #$FF ;delete key?
BNE STR ;no, send whatever pressed
LDA #$88 ;yes, change to backspace
STR JSR SNDCHR ;@@ EXTERNAL HOOK
LDA #$00 ;there wasn't really a char recvd
STA LASTCHAR
JMP LOOP ;and back to main loop!
HNDLBFR TAX ;move character to x-reg
CLC
LDA BUFONOFF ;get buffer status
BEQ BUFDONE ;buffer is off if =0
JSR CHKBUFST ;check buffer status
BCS BUFDONE
LDY #$00
TXA ;grab char. back from x-reg
STA (BUFPTR),Y ;store it
INC BUFPTR
BNE NOPTROV
INC BUFPTR+1 ;increase high byte of buffer
NOPTROV JSR CHKBUFST ;check buffer status again to be sure
BUFDONE RTS ;return to main term loop
OKAYCTRL DFB $80,$88,$87 ;null, bksp, bell
DFB $8D,$8A,$8C ;cr, lf, ff
* add your safe control characters here!
DFB $00 ;end of table
LASTCHAR DS 1 ;last character received goes here
PRSTATUS PHA ;hold accum.
LDA CH
PHA
LDA CV
PHA ;hold horiz & vertical positions
LDA #00
JSR TABV ;VTAB 1
LDA #33 ;HTAB 34
STA CH
LDA BUFONOFF ;get buffer status
JSR PRTONOFF ;print out "on " or "off"
LDA #48
STA CH ;go to next field: "Autosave:"
LDA AUTOSAVE ;get autosave status
JSR PRTONOFF ;print its status
LDA #62
STA CH ;go to next field: "Baud rt:"
LDA BAUDRT ;get baud rate
ASL ;*2
TAY
LDA BAUDNTBL,Y
JSR COUT
LDA BAUDNTBL+1,Y
JSR COUT
PLA
JSR TABV ;restore old vertical tab position
PLA
STA CH ;restore old horiz. tab position
PLA ;get accum. back
RTS
OFFONSTR ASC 'offon '
BAUDNTBL ASC '031224' ;the three baud rates
PRTONOFF PHP
LDY #3
PLP
BNE PRINTON ;value is "on" if non-zero
LDY #0
PRINTON LDX #3
KEEPON LDA OFFONSTR,Y
JSR COUT
INY ;move pointer up
DEX ;move counter down
BNE KEEPON ;print all three characters
RTS
********************************
DOHU JMP HANGUP ;@@ EXTERNAL HOOK
********************************
DOVIEW LDA #<BUFST
STA VIEW0+1
LDA #>BUFST
STA VIEW0+2
LDA BUFPTR
SEC
SBC #$01
STA ENDPT
LDA BUFPTR+1
SBC #$00
STA ENDPT+1
VIEW0 LDA $FFFF ;(self modified)
JSR COUT ;print it
DELVAL LDX #1 ;delay loop
DELVAL1 LDA #25
JSR WAIT
DEX
BNE DELVAL1
LDA KEYBRD ;check keyboard
BPL VIEW3 ;no key, don't process
CMP #"9"+1 ;char. above nine (illegal key)?
BEQ BADKEY ;yes, ignore it
CMP #$B0
BLT NOTSPD ;not a speed control!
STA STROBE
AND #$0F ;strip off top part
STA DELVAL+1
NOTSPD CMP #$A0 ;space?
BNE VIEW2 ;no, check for ESC
BIT STROBE
VIEW1 LDA KEYBRD
BPL VIEW1 ;wait for another key to start
BADKEY STA STROBE
CLC
BCC VIEW3 ;always
VIEW2 CMP #$9B ;esc pressed?
BEQ EXITESC ;yes, exit
CMP #$8D ;return?
BEQ EXITESC ;yes, exit
VIEW3 LDA VIEW0+1 ;check low byte of offset...
CMP ENDPT ;are they equal?
BEQ VIEW4 ;yes, check high byte
INCEM INC VIEW0+1 ;no, they're not the same
BNE GOV0 ;so just jump up the two and go
INC VIEW0+2 ;update high byte
GOV0 JMP VIEW0
VIEW4 LDA VIEW0+2 ;check high byte
CMP ENDPT+1 ;equal with ending point?
BNE INCEM
BIT STROBE ;yes, exit
EXITESC RTS ;return to basic w/key ready
ENDPT DS 2 ;ending point for view
********************************
DOBAUDCH LDA ZPBYTE ;get zero page byte from basic
STA BAUDRT ;store new baud rate
JSR BAUDCH ;@@ EXTERNAL HOOK
JMP PRSTATUS ;update status and return to basic
********************************
DOBREAK JMP BRKSND ;@@ EXTERNAL HOOK
********************************
STOPFLOW LDA #$93 ;ctrl-S (stop flow)
BNE SSPRT
STRTFLOW LDA #$91 ;ctrl-Q (start flow)
SSPRT JMP SNDCHR ;@@ EXTERNAL HOOK
**********************************
* non-modem-specific subroutines *
**********************************
* Subroutine: dial modem (number in input buffer)
DODIAL JSR DOFLUSH ;flush buffer first
JSR DOFLUSH ;be sure nothing else is coming
LDA #0
JSR WAIT ;then hang on for a bit
JSR WAIT
LDY #0
LDX #4 ;send out init string
DIAL1 LDA DIALINIT,Y
JSR SNDCHR ;@@ EXTERNAL HOOK
LDA #128
JSR WAIT ;a small inter-digit delay
INY
DEX
BNE DIAL1
LDX ZPBYTE ;get length of number
LDY #0
DIAL2 LDA PBFR,Y
JSR SNDCHR
LDA #128
JSR WAIT
INY
DEX
BNE DIAL2 ;dial entire number
LDA #$8D ;print final return to put dial in motion
JMP SNDCHR
DIALINIT DFB $8D,"A","T","D" ;modem dialing string
* Subroutine: flush input buffer (clear all excess garbage)
DOFLUSH JSR CHARIN ;@@ EXTERNAL HOOK
BCS DOFLUSH ;keep taking keys out
RTS ;return
* Subroutine: wait for connect (or no connect) from modem
WTCNCT BIT STROBE ;clr kbd
JSR DOFLUSH ;flush out buffer first
LDY #5
LDA #0
DEL01 JSR WAIT ;wait for a spell
DEY
BNE DEL01
JSR DOFLUSH ;clean out the buffer again
LDY #30
WTCNCT0 LDA KEYBRD
BMI USER ;key pressed? get outta here.
JSR CHARIN ;@@ EXTERNAL HOOK
BCC WTCNCT0 ;if nothing back, keep looking
CMP #"C" ;is it "CONNECT"?
BEQ CONNECTX
CMP #"B" ;is it "BUSY"?
BEQ UNABLE ;yes, unable to connect
CMP #"N" ;the "N" in "NO CARRIER" or "NO DIALTONE"?
BEQ UNABLE
DEY
BNE WTCNCT0 ;done with all chances yet?
UNABLE LDA #$00 ;;; code 0 = unable to connect
RTN2 STA ZPBYTE
JSR DOFLUSH ;flush out buffer
RTS
CONNECTX JSR CHARIN ;wait for the final "T"
BCC CONNECTX
CMP #"T"
BNE CONNECTX
LDA #$01 ;;; code 1 = connect
BNE RTN2
USER STA ZPBYTE
BNE RTN2
* Subroutine: wait for "OK" from modem in given time.
WAITOK LDY #10 ;give modem ten chances
LDX #0 ;low byte of timeout counter
LDA #45 ;high byte of timeout counter
STA HICTR
GETOK JSR CHARIN ;@@ EXTERNAL HOOK
BCC CTRDN ;nothing yet, decrease counter
CMP #"K" ;is the the "K" of "OK"?
BEQ ITISOK ;yes, everything's good
DEY
BNE GETOK ;keep checking for that "O"!
BEQ NOTOK ;nope, couldn't find that "O"!
ITISOK CLC
RTS ;carry clear = OK found
NOTOK SEC
RTS ;carry set = OK not found
CTRDN DEX ;move counter down
BNE GETOK ;keep waiting
DEC HICTR ;bump high byte of counter down
LDA HICTR
BNE GETOK ;still doing well
BEQ NOTOK ;nothing good in time! exit
HICTR DS 1 ;high byte of countdown counter for "OK"
* Subroutine: scroll character in on bottom line
SHOWIT PHA ;scroll line in from right
LDA SHOWFLG ;show turned on?
BEQ SHOWEND0
LDY #2
SHOW1 LDA $7D0,Y
DEY
STA $7D0,Y
INY
INY
CPY #38
BNE SHOW1
PLA
DEY
AND #$7F
BPL SHOW2
CMP #'a'
BLT SHOW2
SEC
SBC #$20
SHOW2 CMP #' '
BLT PUTDN
ORA #$80
PUTDN STA $7D0,Y
SHOWEND RTS
SHOWEND0 PLA
RTS ;return
* Subroutine: save registers
SAVEREGS STA REGA
STY REGY
STX REGX
RTS
* Subroutine: restore registers
RESTREGS LDA REGA
LDX REGX
LDY REGY
RTS
REGX DS 1 ;storage for registers
REGY DS 1
REGA DS 1
* Subroutine: check for carrier (carry set=none)
CHKCARR BEQ WEHAVCAR ;if there's no character recvd...
LDY NOCAROFF ;get offset into NO CARRIER string
CMP NOCARR,Y ;is it next char in "NO CARRIER"?
BEQ ANOTHER1 ;yes! move offset up one
LDA #$00
STA NOCAROFF ;zero offset, it's not the next one
WEHAVCAR CLC ;we have carrier since carry is 0
RTS
ANOTHER1 INC NOCAROFF ;increase character offset
INY
CPY #11 ;is it through all eleven characters?
BNE WEHAVCAR ;we still have carrier...for now!
LDA #$00
STA NOCAROFF
LDA #" " ;send out a space to check for carrier
JSR SNDCHR
LDX #0 ;loop for delay
DELLP JSR CHARIN
BCC NOCHAR ;no character yet...
BNE WEHAVCAR ;if ANYTHING comes, it's good
NOCHAR DEX
BNE DELLP ;we've waited long enough...
SEC ;no carrier; carry = 1
RTS
NOCARR ASC "NO CARRIER",8D
NOCAROFF DS 1 ;offset into above string
* Subroutine: hang up telephone
HANGUP JSR STRTFLOW ;send ctrl-Q to start input flow
LDY #11 ;wait for one second before starting
HANGUP0 LDA #195
JSR WAIT
DEY
BNE HANGUP0
LDY #$03 ;send three plusses
HANGUP1 LDA #"+" ;modem into-command-mode char
JSR SNDCHR
JSR DOFLUSH ;flush buffer around before we continue
LDX #3
HANGUP2 LDA #0
JSR WAIT ;wait for a few more milliseconds
DEX
BNE HANGUP2
DEY
BNE HANGUP1
LDX #25
HANGUP3 LDA #0 ;a delay while waiting for "OK" to come
JSR WAIT
DEX
BNE HANGUP3
JSR DOFLUSH ;empty out buffer
LDA #"A" ;send out hangup string
JSR SNDCHR
LDA #"T"
JSR SNDCHR
LDA #"H"
JSR SNDCHR
JSR SNDRTN
LDX #3
HANGUP4 LDA #0
JSR WAIT ;and a teeny bit more delay
DEX
BNE HANGUP4 ;final wait before returning
RTS
* Subroutine: send out return ($8D)
SNDRTN LDA #$8D
JMP SNDCHR
MDMINIT EQU * ;link to initial modem init
MDMEINIT EQU *+3 ;link to modem end init
BRKSND EQU *+6 ;link to send break goes here
SNDCHR EQU *+9 ;link to send character here
CHARIN EQU *+12 ;link to get character here
BAUDCH EQU *+15 ;link to change baud rate
SAV NT.OBJ1 ;save general object
* Now we assemble the other two parts...just another handy
* feature of Merlin.
ENDORG EQU *
** **
** Apple Super Serial Card (or //c) **
** driver routines **
** **
ORG ENDORG
ACTRL EQU $C08B
ACMND EQU $C08A
ASTAT EQU $C089
AXMIT EQU $C088
ARECV EQU AXMIT
:0 JMP MDMINITR ;links to subroutines
:3 JMP MDMEINITR
:6 JMP SNDBRK
:9 JMP SENDCHAR
:12 JMP CHARINP
:15 JMP BAUDCHNG
* Subroutine: modem-specific initialization
MDMINITR LDY SPEC ;get slot offset
LDA #$00
STA BUFRSTRT
STA BUFREND
JSR MLI ;get interrupts rolling
DFB $40 ;ALLOC_INTERRUPT call
DA P:ALL
BCS INITPROB ;error? get outta here.
LDA INT_NUM ;get interrupt number
STA INT_NUM1 ;save it for deallocate call
LDY SPEC
LDA #%00011000 ;8/1, 1200bd, int. baud gen
STA ACTRL,Y
LDA #%00001001 ;turn on xmitter & interrupts
STA ACMND,Y
CLI ;interrupts are now live
LDA ARECV,Y ;dump garbage
JSR SNDRTN ;send a couple of c/rs to wake up mdm
JSR SNDRTN
JSR SNDRTN
LDY #$00
MODMINIT LDA MDMSTRI,Y
BEQ ENDSTR0
JSR SNDCHR
JSR DOFLUSH ;get anything coming back (init string!)
LDA #150
JSR WAIT
INY
BNE MODMINIT
ENDSTR0 JSR DOFLUSH
JSR WAITOK ;wait for "OK" from modem
BCC NOINITPR
JSR WAITOK ;wait for "OK" one more time
BCC NOINITPR
JSR WAITOK ;wait for "OK" one more time
BCC NOINITPR
INITPROB SEC ;no "OK" in time!
RTS
NOINITPR LDA #$02 ;store ID byte : $02 = SupSerCard or //c
STA IDBYTE
JSR SNDRTN ;send out a return
CLC ;clear carry = no problems
RTS ;and that is it. <PHEW!> 8-)
* The below string specifies:
* E0 don't echo back anything we type
* V1 send back normal result codes
* F1 don't echo anything typed (let us do the displaying)
* &c track presence of DCD
MDMSTRI HEX 8D
ASC "ATZ"
HEX 8D
ASC "AT&C1E0V1F1S0=0" ;and S0=0 means don't answer phone
HEX 8D,00
* Parameter tables for allocate and deallocating interrupt
P:ALL DFB $02 ;two parameters
INT_NUM DS 1 ;interrupt # is returned here
DA RDINT ;point to interrupt handler
P:DEALL DFB $01 ;only one parameter
INT_NUM1 DS 1 ;fill in interrupt number here
* Subroutine: modem end init...this is called when modem is
* done being used (when program ends). Turn buffer off here.
MDMEINITR SEI ;turn off interrupts
LDY SPEC
LDA #%00000010 ;turn interrupts & xmitter off
STA ACMND,Y
JSR MLI ;turn off buffer
DFB $41 ;DEALLOC_INTERRUPT
DA P:DEALL
CLI ;allow interrupts now
RTS ;return; we're done
* Subroutine: change baud rate. 0=300, 1=1200, 2=2400
BAUDCHNG TAY
LDA #%00010000 ;8 data, one stop, int clock
ORA BAUDS,Y ;add on bottom nybble
LDY SPEC
STA ACTRL,Y ;set new baud rate
RTS
BAUDS DFB %00000110 ;300 baud image
DFB %00001000 ;1200 baud image
DFB %00001010 ;2400 baud image
* Subroutine: send break signal
SNDBRK LDY SPEC
LDA #%00001101 ;send a BRK
STA ACMND,Y
LDA #%00001001 ;back to normal xmitter
STA ACMND,Y
RTS
* Subroutine: get key from modem (c=1 if there; c=0 if none)
CHARINP JSR SAVEREGS
SEI ;stop interrupts for a moment
LDY BUFRSTRT ;get buffer start
CPY BUFREND
BEQ EXITIN ;no character waiting
LDA IOBFR,Y ;get the keypress
INC BUFRSTRT ;move character pointer up
ORA #$80
CLI ;turn interrupts back on
PHA
JSR SHOWIT ;scroll it in
JSR RESTREGS
PLA ;get key back
SEC ;here's a key!
RTS ;return
EXITIN CLI ;turn interrupts back on
JSR RESTREGS
LDA #$00 ;no character
CLC
RTS ;return to caller
* Subroutine: send character in accum.
SENDCHAR PHA ;save character for a moment
JSR SAVEREGS
SEND0 LDY SPEC ;are we ready to go?
LDA ASTAT,Y
AND #%00010000
BEQ SEND0 ;we aren't ready yet
LDA #10 ;wait for a teeny moment
JSR WAIT
PLA ;get character to send back
STA AXMIT,Y ;send it
JSR RESTREGS
RTS ;and return
* Special: interrupt vector for char. read
RDINT CLD ;this is a valid handler
SEI
LDY SPEC ;check status register
LDA ASTAT,Y
AND #%00001000 ;is the receive register full?
BEQ NOTOURS ;no, some other interrupt popped up
LDA ARECV,Y ;get data byte (finally!)
ORA #$80 ;set the high bit
CMP #$8A
BEQ EXITINT ;ignore linefeed lous
CMP #$80
BEQ EXITINT ;and nulls
LDY BUFREND
STA IOBFR,Y
INC BUFREND ;increase length of buffer by one
EXITINT CLC ;claim this interrupt
RTNINT CLI
RTS
NOTOURS SEC ;not our interrupt!
BCS RTNINT ;always
BUFRSTRT DS 1 ;pointer to star of buffer
BUFREND DS 1 ;pointer to end of buffer
IOBFR DS 256 ;i/o buffer (a FIFO stack)
SAV NT.OBJ2 ;save super serial object
** **
** Apple IIgs modem-port specific **
** driver routines **
** **
ORG ENDORG ;now do second half
XC ;the GS can handle 65c02 opcodes
:0 JMP XMDMINIT ;specific links to subroutines
:3 JMP XMDMEINIT
:6 JMP XBRKSND
:9 JMP XSNDCHR
:12 JMP XCHARIN
:15 JMP XBAUDCH
* Subroutine: modem-specific initialization
XMDMINIT LDA #$0D ;init routine jump address
JSR DOIT
LDY #$00
MDINIT0 LDA MDMISTR,Y
BEQ ENDSTR
JSR SNDCHR
INY
BNE MDINIT0
ENDSTR JSR DOFLUSH
JSR WAITOK ;wait for "OK" from modem
BCC NOIERR
JSR WAITOK ;wait for "OK" one more time
BCC NOIERR
JSR WAITOK ;wait for "OK" from modem
BCC NOIERR
SEC ;no "OK" in time!
RTS
NOIERR JSR SCA ;wake buffering up
LDA #"B"
JSR SNDCHR
LDA #"E"
JSR SNDCHR
JSR SCA
LDA #"M" ;mask linefeeds coming in
JSR SNDCHR
LDA #"E"
JSR SNDCHR
JSR SCA ;set format to 8N1:
LDA #"0" ;set data/stop bits to 8/1
JSR SNDCHR
LDA #"D"
JSR SNDCHR
JSR SCA ;change parity to none
LDA #"0"
JSR SNDCHR
LDA #"P"
JSR SNDCHR
LDA #$01 ;store ID byte : $01 = IIGS
STA IDBYTE
JSR SNDRTN ;send out a return
CLC ;clear carry = no problems
RTS ;and that is it. <PHEW!> 8-)
* The below string specifies:
* E0 don't echo back anything we type
* V1 send back normal result codes
* F1 don't echo anything typed (let us do the displaying)
MDMISTR HEX 8D
ASC "ATZ"
HEX 8D
ASC "AT&C1E0V1F1S0=0" ;and S0=0 means don't answer phone
HEX 8D,00
* Subroutine: modem end init...this is called when modem is
* done being used (when program ends). Turn buffer off here.
XMDMEINIT RTS ;none for the GS
* Subroutine: change baud rate. 0=300, 1=1200, 2=2400
XBAUDCH PHA
LDA #"0"
STA BAUDSTR+1
PLA
BEQ DO300
DEC A
BEQ DO1200
LDA #"1"
STA BAUDSTR+1
LDA #"0"
BNE BAUDCH1
DO300 LDA #"6"
BNE BAUDCH1
DO1200 LDA #"8"
BAUDCH1 STA BAUDSTR+2
LDY #0
BAUDCH2 LDA BAUDSTR,Y
STA CHAR
STY REGY
JSR KEEPCHK ;use special send routine for CTRL-A
LDY REGY
INY
CPY #4 ;send all four yet?
BNE BAUDCH2
RTS ;return to caller
BAUDSTR DFB $81 ;ctrl-a
ASC "08B" ;the 08 is changed to 06, 08, or 10
* Subroutine: send CTRL-A (modem wake-up signal)
SCA LDA #$81
SCA2 STA CHAR ;Subroutine: send ANY char in accum.
JMP KEEPCHK ;send it and return to caller
* Subroutine: send 233-ms break signal
XBRKSND JSR SCA ;send ctrl-A
LDA #"S"
JMP SNDCHR ;send out the "S" to do a break
* Subroutine: get key from modem (c=1 if there; c=0 if none)
XCHARIN JSR SAVEREGS
LDA #$01
STA TEMP1
LDA #$10 ;status call
JSR DOIT ;check if key received
BCC XIT ;no, don't take anything, carry clr
LDA #$0E ;read call
JSR DOIT ;get character
ORA #$80 ;set high bit
PHA
JSR SHOWIT ;put it into the scroll line
JSR RESTREGS
PLA
SEC ;carry set = key available
RTS ;return
XIT JSR RESTREGS
LDA #$00 ;no character
CLC
RTS ;return to caller
* Subroutine: send character in accum.
XSNDCHR STA CHAR ;save character to send
JSR SAVEREGS
CMP #$81 ;is it special control character?
BNE KEEPCHK ;no, don't worry about it
JSR KEEPCHK ;send CTRL-A
LDA #$82 ;change controller char to CTRL-B temp
JSR SCA2
JSR SCA ;send control-A (really send it now)
LDA #$82
JSR SCA2 ;send controller char (CTRL-B for now)
LDA #$81 ;and change it back to CTRL-A
STA CHAR
KEEPCHK LDA #$00 ;are you ready for output?
STA TEMP1
LDA #$10 ;status call
JSR DOIT
BCC KEEPCHK ;keep checking until it's ready
LDA CHAR
STA TEMP1
LDA #$0F ;write it out
JSR DOIT
LDA TEMP1 ;get character
JSR RESTREGS
RTS ;and return
CHAR DS 1 ;character to send
* Subroutine: call routine via jump table for Pascal protocol.
DOIT STA EXTPTR ;call routine pointed to via jump addresses
LDY #$00
LDA (EXTPTR),Y
SEC
SBC #$01
STA TEMP2
LDA $07
PHA
LDA TEMP2
PHA
LDA TEMP1
LDX EXTPTR+1
LDY SPEC
CLC
RTS ;call extended interface
TEMP1 DS 1 ;temporary storage for rtn jump pointer
TEMP2 DS 1 ;temporary storage for high byte of jmp
SAV NT.OBJ3 ;save this object code, and we're done